from genshi import Markup
from genshi.template.markup import MarkupTemplate

from sqlalchemy.orm import object_mapper

from tortuga.util import AttrDict
from tortuga.models import Page, Template

__all__ = ['render']

###############################
# !!! LOOK OUT !!!
# !!! LOOK OUT !!!
#
# This is an overly simplistic way to render content, with no caching, no support for
# anything besides genshi, no way to template a container, etc etc.  This API will change
# drastically in a very short amount of time, so don't rely on it for anything please.
#
# !!! LOOK OUT !!!
# !!! LOOK OUT !!!
###############################

def render(obj=None, **data):
    # Error checking
    if not isinstance(obj, Page):
        raise NotImplemented("'%s' Content type is not supported at this time" % type(obj))
    obj_template = getattr(obj, 'template', None)
    if not obj_template or not isinstance(obj_template, Template):
        raise NotImplemented("Cannot render content without a Template")
    engine = obj_template.engine
    if unicode(engine) not in [u'genshi']:
        raise NotImplemented("'%s' Template engine is not supported at this time" % engine)
    
    # Create a closure that can render a container for this content instance
    def render_container(name):
        output = ''
        for g in obj.containers[name].gadgets:
            output += Markup("<div class='%s' id='%s'>%s</div>") % (
                g.content_type, 
                g.gadget_id, 
                Markup(g.render())
            )
        return output
        
    # Construct a namespace of data to pass to the template
    namespace_data = dict(tortuga=AttrDict(dict(render_container=render_container)))
    for p in object_mapper(obj).iterate_properties:
        namespace_data[p.key] = getattr(obj, p.key, None)
    
    # Render the content instance using its template
    if obj_template.code is not None:
        template = MarkupTemplate(obj_template.code)
        stream = template.generate(**namespace_data)
        return stream.render(method='xhtml')